﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Control : MonoBehaviour
{
    Ship ArmShip
    {
        get { return m_ArmShip; }
        set { 
            m_ArmShip = value;
            if (m_Ship)
                m_Ship.ArmShip(m_ArmShip);
        }
    }
    public Camera ControlCamera;
    public ParticleSystem EffectBackground;
    public WeaponGroupPanel m_WeaponGroupUI;

    public AudioSource m_SwitchWeaponGroupSound1;
    public AudioSource m_SwitchWeaponGroupSound2;
    public AudioSource m_SwitchWeaponGroupSound3;
    public AudioSource m_SwitchWeaponGroupSound4;
    public GameObject m_ArmCenterIcon;

    public GameObject m_AndroidControlePanel;
    public ShipCallback OnControleShipChanged = new ShipCallback();

    Ship m_ArmShip = null;

    bool m_EnabledShowRange = true;
    public int m_CurrentWeaponGroup=1;
    public Vector3 m_FoucsPosition;
    int m_ShipOprate = 0;//是否正在操控舰船

#if UNITY_ANDROID
    int m_ArmTouchID =-1;
#endif
    bool m_AutoFeature = false;
    public bool m_LockMove = false;

    Vector3 m_CameraPosition;
    public bool m_IsFreeCamera = false;
    public float m_CameraZoom = -1;
    public enum ShipOprate
    {
        MOVE_UP,
        MOVE_DOWN,
        MOVE_RIGHT,
        MOVE_LEFT,
        ROT_LEFT,
        ROT_RIGHT,
    }
    public Ship ControlShp
    {
        set
        {
            if (value)
            {
                if(m_Ship && m_Ship.GetComponent<AudioListener>())
                    m_Ship.GetComponent<AudioListener>().enabled = false;

                m_Ship = value;

                EditorMode editorMode = GetComponent<EditorMode>();
                m_Ship.setHighLightEnabled(editorMode.enabled);

                if (m_Ship.m_ShipStruct.Influence != InfluenceMG.INFLUENCE_EGG &&
                    !InfluenceMG.get().IsPlayer(m_Ship.m_ShipStruct.m_Influence))
                    m_Ship.m_ShipStruct.Influence = InfluenceMG.INFLUENCE_PLAYER;
                AudioListener listener = m_Ship.GetComponent<AudioListener>();
                if (null == listener)
                    listener = m_Ship.gameObject.AddComponent<AudioListener>();
                listener.enabled = true;
                if (m_Ship.GetComponent<Driver>())
                    m_Ship.GetComponent<Driver>().m_IsManual = true;
                m_Ship.EnabledShowRange = m_EnabledShowRange;
                m_Ship.SetShowRange(m_CurrentWeaponGroup);
                var shipPosition = m_Ship.transform.position;
                shipPosition.z = -1000;
                ControlCamera.transform.position = shipPosition;
                Commander.Instance.InitShip(m_Ship);
                OnControleShipChanged.Invoke(m_Ship);
            }
        }
        get { return m_Ship; }
    }
    public Ship m_Ship;

    private void Awake()
    {
        if (m_Ship)
        {
            ControlShp = m_Ship;
        }
#if UNITY_ANDROID
        if(m_AndroidControlePanel)
            m_AndroidControlePanel.gameObject.SetActive(true);
#else
        if(m_AndroidControlePanel)
            m_AndroidControlePanel.gameObject.SetActive(false);
#endif
        if(m_CameraZoom == -1)
            m_CameraZoom = Camera.main.orthographicSize;
    }
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        checkHotKey();
        updateCamera();
        EditorMode editorMode = GetComponent<EditorMode>();
        if (editorMode.enabled)
            return;
        Arm();
        checkMove();
        checkFire();
        m_ShipOprate = 0;
    }

    public void CheckTarget()
    {
        //   如果检测到敌方在自己的攻击范围内，则切换目标
        var selfInfluence = m_Ship.m_ShipStruct.Influence;
        float checkRange = m_Ship.m_ShipStruct.DetectRange;
        List<ArmTarget> targets = ShipManager.Instance.CheckShipInRange(m_Ship.transform.position, checkRange, m_Ship.m_ShipStruct.Influence);

        if (null != targets)
        {
            m_Ship.SmashTarget(targets, false);

            var nearTarget = Driver.findMostNearShip(targets);
            if (nearTarget != null)
            {
                ArmShip =  nearTarget.Target.GetComponent<Ship>();
            }
        }
    }
    void Arm()
    {
        bool isSelect = false;
#if UNITY_ANDROID
        for (int i = 0; i < Input.touchCount; ++i)
        {
            var touch = Input.GetTouch(i);
            if (touch.phase == TouchPhase.Stationary &&
                !UtilsUnity.IsOnUI(touch.position))
            {
                m_ArmTouchID = touch.fingerId;
                m_FoucsPosition = ControlCamera.ScreenToWorldPoint(touch.position);
                isSelect = true;
            }
            else if (touch.phase == TouchPhase.Ended)
            {
                m_ArmTouchID = -1;
            }

            if (m_ArmTouchID == touch.fingerId &&
                touch.phase == TouchPhase.Moved)
            {
                m_FoucsPosition = ControlCamera.ScreenToWorldPoint(touch.position);
            }

        }
#else
        m_FoucsPosition = ControlCamera.ScreenToWorldPoint(Input.mousePosition);
        m_FoucsPosition.z = 0;


        if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
        {
            isSelect=true;
        }
#endif

        if (isSelect)
        {
            if(ArmShip != null)
                ArmShip = null;
            int layerMask = 1 << 9;
            RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, 100000, layerMask);
            if (hit.collider != null)
            {
                var obj = hit.collider.gameObject;
                var ship = UtilsGame.FindShip(obj);
                if (ship && ArmShip != ship)
                    ArmShip = ship;
            }
        }

        if (ArmShip)
            m_FoucsPosition= ArmShip.transform.position;
    }

    void checkMove()
    {
        if (m_Ship != null)
        {
            m_Ship.UpdateTransfomrOnline();
            if (Input.GetKey(KeyCode.W))
                ShipMoveForward();
            if (Input.GetKey(KeyCode.S))
                ShipMoveBack();

            if(Input.GetKey(KeyCode.LeftShift))
            {
                m_Ship.Focus(m_FoucsPosition);
                if (Input.GetKey(KeyCode.A))
                    ShipMoveLeft();
                if (Input.GetKey(KeyCode.D))
                    ShipMoveRight();
            }
            else
            {
                if (Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.LeftControl))
                    ShipRotLeft();

                if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.LeftControl))
                    ShipRotRight();
            }
        }
    }

    void checkFire()
    {
        if (!m_Ship)
            return;

        float armScale = 0.5f;
        if (ArmShip)
            armScale = 1.5f;

        m_Ship.arm(m_FoucsPosition, m_CurrentWeaponGroup);

        if (m_FoucsPosition != Vector3.zero)
            m_ArmCenterIcon.transform.position = UtilsUnity.GetPositionInScreen(Camera.main.WorldToScreenPoint(m_FoucsPosition), m_ArmCenterIcon.GetComponent<RectTransform>().sizeDelta, UtilsUnity.Align.ALIGN_CENTER);
        float scale = ((Mathf.Sin(Time.time * 6 * armScale) + 1) / 5)+0.5f * armScale;
        m_ArmCenterIcon.transform.localScale = new Vector3(scale, scale, 1);

#if UNITY_STANDALONE_WIN
        if (Input.GetMouseButton(0) && !EventSystem.current.IsPointerOverGameObject())
            Fire();
        if (Input.GetMouseButtonUp(0) && !EventSystem.current.IsPointerOverGameObject())
            FireUp();
#endif

        if (Input.GetKey(KeyCode.Q) && !EventSystem.current.IsPointerOverGameObject())
        {
            SetUAVState(UAVFunction.State.STATE_FIGHT);
        }
        else if (Input.GetKey(KeyCode.E) && !EventSystem.current.IsPointerOverGameObject())
        {
            SetUAVState(UAVFunction.State.STATE_BACK);
        }
        else if (Input.GetKey(KeyCode.R) && !EventSystem.current.IsPointerOverGameObject())
        {
            SetUAVState(UAVFunction.State.STATE_PROTECTED);
        }

        if (Input.GetKeyDown(KeyCode.Space) && !EventSystem.current.IsPointerOverGameObject())
            m_Ship.SetFeatureSwitch(!m_Ship.m_Switch);

        if (Input.GetKey(KeyCode.F) && !EventSystem.current.IsPointerOverGameObject())
            LaunchSkill();

        if (Input.GetKeyUp(KeyCode.F))
            CancleSkill();

        if (Input.GetKeyDown(KeyCode.C) && !EventSystem.current.IsPointerOverGameObject())
            LaunchiHook();


        if (Input.GetKeyDown(KeyCode.Alpha1) && !EventSystem.current.IsPointerOverGameObject())
            SwitchWeaponGroup(1);
        if (Input.GetKeyDown(KeyCode.Alpha2) && !EventSystem.current.IsPointerOverGameObject())
            SwitchWeaponGroup(2);
        if (Input.GetKeyDown(KeyCode.Alpha3) && !EventSystem.current.IsPointerOverGameObject())
            SwitchWeaponGroup(3);
        if (Input.GetKeyDown(KeyCode.Alpha4) && !EventSystem.current.IsPointerOverGameObject())
            SwitchWeaponGroup(4);
    }

    public void SetUAVState(UAVFunction.State state)
    {
        m_Ship.SetUAVState(state, m_CurrentWeaponGroup);
    }
    public void OnQ()
    {
        SetUAVState(UAVFunction.State.STATE_FIGHT);
    }
    public void OnR()
    {
        SetUAVState(UAVFunction.State.STATE_PROTECTED);
    }
    public void OnE()
    {
        SetUAVState(UAVFunction.State.STATE_BACK);
    }
    public void SwitchWeaponGroup(int group)
    {
        switch(group)
        {
            case 1:
                if(m_SwitchWeaponGroupSound1)
                    m_SwitchWeaponGroupSound1.Play();
                break;
            case 2:
                if (m_SwitchWeaponGroupSound2)
                    m_SwitchWeaponGroupSound2.Play();
                break;
            case 3:
                if (m_SwitchWeaponGroupSound3)
                    m_SwitchWeaponGroupSound3.Play();
                break;
            case 4:
                if (m_SwitchWeaponGroupSound4)
                    m_SwitchWeaponGroupSound4.Play();
                break;
        }
        m_CurrentWeaponGroup = group;
        m_Ship.SetShowRange(m_CurrentWeaponGroup);
    }
    void updateCamera()
    {

        CameraZoom();
        EditorMode editorMode = GetComponent<EditorMode>();
        if (m_Ship && !editorMode.enabled)
        {
            if(!m_IsFreeCamera)
                m_CameraPosition = m_Ship.transform.position;
            var particalShpe = EffectBackground.shape;
            particalShpe.position = m_CameraPosition;
            m_CameraPosition.z = -1000;
#if UNITY_ANDROID
            var offset = new Vector3(0,0,0);
#else
            var mousePosition = Input.mousePosition;
            float xS = mousePosition.x / UnityEngine.Screen.width  * 2-1;
            float yS = mousePosition.y / UnityEngine.Screen.height * 2-1;
            var screenPosScale = new Vector3(xS, yS);
            var offset = screenPosScale * ((ControlCamera.orthographicSize * Mathf.Sin(screenPosScale.magnitude)) *0.8f);
#endif
            ControlCamera.transform.position = m_CameraPosition + offset;
        }
    }

    void checkHotKey()
    {
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            m_EnabledShowRange = !m_EnabledShowRange;
            m_Ship.EnabledShowRange = m_EnabledShowRange;
            m_Ship.SetShowRange(m_CurrentWeaponGroup);
        }

        if(Input.GetKeyDown(KeyCode.U) && m_WeaponGroupUI != null)
        {
            if(m_WeaponGroupUI.gameObject.activeSelf)
            {
                m_WeaponGroupUI.Hide();
            }
            else
            {
                m_WeaponGroupUI.Show(m_Ship);
            }
        }

        /// Test Code 
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            Time.timeScale += 1;
        }
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            Time.timeScale -= 1;
        }

        if(Input.GetKeyDown(KeyCode.L))
        {
            EditorMode editorMode = GetComponent<EditorMode>();
            editorMode.setEnabled(!editorMode.enabled);
        }
        if (Input.GetKeyDown(KeyCode.P))
        {
            m_IsFreeCamera = !m_IsFreeCamera;
        }
    }

    public void setEditModeEnabled(bool isEnabled)
    {
        if(isEnabled == true)
        {
            var position = m_Ship.transform.position;
            position.z = -1000;
            ControlCamera.transform.position = position;
        }
        EditorMode editorMode = GetComponent<EditorMode>();
        editorMode.setEnabled(isEnabled);

        m_Ship.setHighLightEnabled(isEnabled);
    }

    bool wasZoomingLastFrame = false;
    Vector2[] lastZoomPositions;
    void CameraZoom()
    {
#if UNITY_ANDROID
        if(Input.touchCount == 2 && m_ShipOprate == 0)
        {
            Vector2[] newPositions = new Vector2[] { 
                new Vector2(Input.GetTouch(0).position.x / Screen.width, Input.GetTouch(0).position.y / Screen.height),
                new Vector2(Input.GetTouch(1).position.x / Screen.width, Input.GetTouch(1).position.y / Screen.height)};

            if (!wasZoomingLastFrame)
            {
                lastZoomPositions = newPositions;
                wasZoomingLastFrame = true;
            }
            else
            {
                // Zoom based on the distance between the new positions compared to the 
                // distance between the previous positions.
                float newDistance = Vector2.Distance(newPositions[0], newPositions[1]);
                float oldDistance = Vector2.Distance(lastZoomPositions[0], lastZoomPositions[1]);
                float offset = newDistance - oldDistance;
        
                m_CameraZoom = Mathf.Clamp(m_CameraZoom - offset * m_CameraZoom, 2, 30);
                lastZoomPositions = newPositions;
            }
        }
        else
        {
            wasZoomingLastFrame = false;
        }
        if (cameraInitCount > cameraInitCountMax &&
            Mathf.Abs(ControlCamera.orthographicSize - m_CameraZoom) > 0.1f)
        {
            ControlCamera.orthographicSize = Mathf.Lerp(ControlCamera.orthographicSize, m_CameraZoom, Time.deltaTime * 3);
        }
#else
        if (ControlCamera != null && !EventSystem.current.IsPointerOverGameObject())
        {
            m_CameraZoom = Mathf.Clamp(m_CameraZoom - Input.GetAxis("Mouse ScrollWheel") * m_CameraZoom, 2, 30);
            if(cameraInitCount > cameraInitCountMax)
            {
                ControlCamera.orthographicSize = Mathf.Lerp(ControlCamera.orthographicSize, m_CameraZoom, Time.deltaTime * 3);
            }
        }
#endif
        cameraInitCount += Time.deltaTime;
    }
    float cameraInitCount=0;
    float cameraInitCountMax=0.5f;

    public void SetAutoFire(bool autoFire)
    {
        if (m_Ship)
            m_Ship.m_AutoFire2 = autoFire;
    }

    public void LaunchiHook(int source = 0)
    {
        m_Ship.PullHook(m_FoucsPosition);
    }

    public void LaunchSkill(int source=0)
    {
        if(m_Ship.UseSkill == false)
        {
            if (UtilsGame.IsOnline())
                m_Ship.LaunchSkillInClient();
            else
                m_Ship.LaunchSkill();
            m_Ship.UseSkill = true;
        }
        m_ShipOprate = source;
    }
    public void CancleSkill(int source=0)
    {
        m_Ship.UseSkill = false;
        m_ShipOprate = source;
    }
    public void Fire(int source = 0)
    {
        if(m_Ship.m_FireGroup == m_CurrentWeaponGroup)
            return;
        m_Ship.m_FireGroup = m_CurrentWeaponGroup;
        if(UtilsGame.IsOnline())
            m_Ship.CmdSetFireGroup(m_CurrentWeaponGroup);
        m_ShipOprate = source;
    }
    public void FireUp(int source = 0)
    {
        m_Ship.m_FireGroup = -1;
        if (UtilsGame.IsOnline())
            m_Ship.CmdSetFireGroup(-1);
        m_Ship.FireUp(source);
    }

    public void ShipMoveForward(int source = 0)
    {
        if (m_IsFreeCamera)
            MoveCamera(ShipOprate.MOVE_UP);
        else
            m_Ship.moveForward();
        m_ShipOprate = source;
    }
    public void ShipMoveBack(int source = 0)
    {
        if (m_IsFreeCamera)
            MoveCamera(ShipOprate.MOVE_DOWN);
        else
            m_Ship.moveBack();
        m_ShipOprate = source;
    }
    public void ShipMoveLeft(int source = 0)
    {
        if (m_IsFreeCamera)
            MoveCamera(ShipOprate.MOVE_LEFT);
        else
            m_Ship.moveLeft();
        m_ShipOprate = source;
    }
    public void ShipMoveRight(int source = 0)
    {
        if (m_IsFreeCamera)
            MoveCamera(ShipOprate.MOVE_RIGHT);
        else
            m_Ship.moveRight();
        m_ShipOprate = source;
    }

    public void ShipRotLeft(float power = 1, int source = 0)
    {
        if (m_IsFreeCamera)
            MoveCamera(ShipOprate.MOVE_LEFT);
        else
            m_Ship.rotationLeft(power);
        m_ShipOprate = source;
    }
    public void ShipRotRight(float power = 1, int source = 0)
    {
        if (m_IsFreeCamera)
            MoveCamera(ShipOprate.MOVE_RIGHT);
        else
            m_Ship.rotationRight(power);
        m_ShipOprate = source;
    }
    public ShipOprate ShipFoucs(Vector3 direction, int source)
    {
        m_Ship.Focus(m_Ship.transform.position + direction);

        return ShipOprate.MOVE_DOWN;
    }

    public ShipOprate ShipArm2(Vector3 direction, int source)
    {
        if (ArmShip)
            return ShipOprate.MOVE_UP;

        m_FoucsPosition = m_Ship.transform.position + direction * 6;

        ShipOprate directionFlag = 0;
        if (Vector3.Angle(Vector3.up, direction) < 45)
        {
            directionFlag = ShipOprate.MOVE_UP;
        }
        else if (Vector3.Angle(Vector3.down, direction) < 45)
        {
            directionFlag = ShipOprate.MOVE_DOWN;
        }
        else if (Vector3.Angle(Vector3.left, direction) < 45)
        {
            //relativePos = Quaternion.AngleAxis(90 * Time.deltaTime, new Vector3(0, 0, 1)) * relativePos;
            directionFlag = ShipOprate.MOVE_LEFT;
        }
        else if (Vector3.Angle(Vector3.right, direction) < 45)
        {
            //relativePos = Quaternion.AngleAxis(90 * Time.deltaTime, new Vector3(0, 0, -1)) * relativePos;
            directionFlag = ShipOprate.MOVE_RIGHT;
        }
        m_ShipOprate = source;
        return directionFlag;
    }
    public void MoveCamera(ShipOprate oprate)
    {
        Vector3 direction = new Vector3();
        switch(oprate)
        {
            case ShipOprate.MOVE_UP:
                direction = Vector3.up;
                break;
            case ShipOprate.MOVE_DOWN:
                direction = Vector3.down;
                break;
            case ShipOprate.MOVE_RIGHT:
                direction = Vector3.right;
                break;
            case ShipOprate.MOVE_LEFT:
                direction = Vector3.left;
                break;
        }
        MoveCamera(direction);
    }
    public void MoveCamera(Vector3 direction)
    {
        Vector3 offset = direction * ControlCamera.orthographicSize * Time.deltaTime;
        m_CameraPosition += offset;
    }
    public ShipOprate ShipMove(Vector3 direction, int source)
    {
        ShipOprate directionFlag = 0;

        if (Vector3.Angle(m_Ship.transform.up, direction) < 45)
        {
            ShipMoveForward(1);
            directionFlag = ShipOprate.MOVE_UP;
        }
        else if (Vector3.Angle(-m_Ship.transform.up, direction) < 45)
        {
                ShipMoveBack(1);

            directionFlag = ShipOprate.MOVE_DOWN;
        }
        else if (Vector3.Angle(-m_Ship.transform.right, direction) < 45)
        {
                ShipMoveLeft(1);
            directionFlag = ShipOprate.MOVE_LEFT;
        }
        else if (Vector3.Angle(m_Ship.transform.right, direction) < 45)
        {
                ShipMoveRight(1);
            directionFlag = ShipOprate.MOVE_RIGHT;
        }
        m_ShipOprate = source;
        return directionFlag;
    }

    public void SetFreeCamera(bool freeCamera)
    {
        m_IsFreeCamera = freeCamera;
    }

    public ShipOprate ShipEasyMove(Vector3 direction, int source)
    {
        ShipOprate directionFlag = 0;
        if (Vector3.Angle(m_Ship.transform.up, direction) < 60)
        {
            ShipMoveForward(1);
            directionFlag = ShipOprate.MOVE_UP;
        }
        else if (Vector3.Angle(-m_Ship.transform.up, direction) < 60)
        {
            ShipMoveBack(1);
            directionFlag = ShipOprate.MOVE_DOWN;
        }
        else if (Vector3.Angle(-m_Ship.transform.right, direction) < 45)
        {
            if (m_LockMove)
                ShipMoveLeft(1);
            else
                ShipMoveForward(1);
            directionFlag = ShipOprate.MOVE_LEFT;
        }
        else if (Vector3.Angle(m_Ship.transform.right, direction) < 45)
        {
            if (m_LockMove)
                ShipMoveRight(1);
            else
                ShipMoveForward(1);
            directionFlag = ShipOprate.MOVE_RIGHT;
        }

        if (m_LockMove)
        {

        }
        else
        {
            ShipFoucs(direction, source);
        }
        m_ShipOprate = source;
        return directionFlag;
    }

    public void SetAutoFeatrue(bool isEnabled)
    {
        m_Ship.SetFeatureSwitch(isEnabled);
    }
}
